/**
 * Excel导出工具类
 * 基于ExcelJS库实现，提供简单易用的API接口
 * 函数式风格实现
 */
import ExcelJS from 'exceljs';
import fs from 'fs';
import path from 'path';
import log4js from './log4js.js';

const logger = log4js.getLogger();

/**
 * 创建Excel导出工具
 * @param {Object} options 配置选项
 * @param {String} options.defaultSheetName 默认工作表名称
 * @param {String} options.defaultFilePath 默认文件保存路径
 * @returns {Object} Excel导出工具对象
 */
const createExcelExporter = (options = {}) => {
    // 内部状态
    const state = {
        defaultSheetName: options.defaultSheetName || '工作表1',
        defaultFilePath: options.defaultFilePath || './export',
        workbook: new ExcelJS.Workbook(),
        currentWorksheet: null
    };

    /**
     * 创建新的工作表
     * @param {String} sheetName 工作表名称
     * @returns {Object} 导出工具对象，支持链式调用
     */
    const createSheet = (sheetName = state.defaultSheetName) => {
        state.currentWorksheet = state.workbook.addWorksheet(sheetName);
        return exporter;
    };

    /**
     * 设置列定义
     * @param {Array} columns 列定义数组，例如：[{header: '姓名', key: 'name', width: 20}]
     * @returns {Object} 导出工具对象，支持链式调用
     */
    const setColumns = (columns) => {
        if (!state.currentWorksheet) {
            createSheet();
        }
        state.currentWorksheet.columns = columns;
        return exporter;
    };

    /**
     * 添加表头
     * @param {Array} headers 表头数组，例如：['姓名', '年龄', '性别']
     * @param {Object} options 表头样式选项
     * @returns {Object} 导出工具对象，支持链式调用
     */
    const addHeader = (headers, options = {}) => {
        if (!state.currentWorksheet) {
            createSheet();
        }

        // 添加表头行
        const headerRow = state.currentWorksheet.addRow(headers);

        // 设置表头样式
        headerRow.eachCell((cell) => {
            cell.font = {
                bold: true,
                size: options.fontSize || 12,
                color: { argb: options.fontColor || 'FF000000' }
            };
            cell.fill = {
                type: 'pattern',
                pattern: 'solid',
                fgColor: { argb: options.bgColor || 'FFF2F2F2' }
            };
            cell.border = {
                top: { style: 'thin' },
                left: { style: 'thin' },
                bottom: { style: 'thin' },
                right: { style: 'thin' }
            };
            cell.alignment = {
                vertical: 'middle',
                horizontal: 'center'
            };
        });

        return exporter;
    };

    /**
     * 添加数据行
     * @param {Array} rows 数据行数组，可以是对象数组或二维数组
     * @param {Object} options 样式选项
     * @returns {Object} 导出工具对象，支持链式调用
     */
    const addRows = (rows, options = {}) => {
        if (!state.currentWorksheet) {
            createSheet();
        }

        // 添加数据行
        state.currentWorksheet.addRows(rows);

        // 设置数据行样式
        if (options.applyStyle !== false) {
            const startRow = state.currentWorksheet.rowCount - rows.length + 1;
            const endRow = state.currentWorksheet.rowCount;

            for (let i = startRow; i <= endRow; i++) {
                const row = state.currentWorksheet.getRow(i);
                row.eachCell((cell) => {
                    cell.border = {
                        top: { style: 'thin' },
                        left: { style: 'thin' },
                        bottom: { style: 'thin' },
                        right: { style: 'thin' }
                    };
                    cell.alignment = {
                        vertical: 'middle',
                        horizontal: options.align || 'left'
                    };
                });
            }
        }

        return exporter;
    };

    /**
     * 设置列宽
     * @param {Object} widths 列宽配置，例如：{A: 10, B: 20}
     * @returns {Object} 导出工具对象，支持链式调用
     */
    const setColumnWidths = (widths) => {
        if (!state.currentWorksheet) {
            createSheet();
        }

        Object.keys(widths).forEach(col => {
            state.currentWorksheet.getColumn(col).width = widths[col];
        });

        return exporter;
    };

    /**
     * 合并单元格
     * @param {String} range 合并范围，例如：'A1:C1'
     * @returns {Object} 导出工具对象，支持链式调用
     */
    const mergeCells = (range) => {
        if (!state.currentWorksheet) {
            createSheet();
        }

        state.currentWorksheet.mergeCells(range);
        return exporter;
    };

    /**
     * 设置单元格样式
     * @param {String} cellRef 单元格引用，例如：'A1'
     * @param {Object} style 样式对象
     * @returns {Object} 导出工具对象，支持链式调用
     */
    const setCellStyle = (cellRef, style) => {
        if (!state.currentWorksheet) {
            createSheet();
        }

        const cell = state.currentWorksheet.getCell(cellRef);
        Object.assign(cell, style);
        return exporter;
    };

    /**
     * 保存Excel文件
     * @param {String} filePath 文件保存路径
     * @returns {Promise} 保存结果Promise
     */
    const saveToFile = async (filePath) => {
        try {
            // 确保目录存在
            const dir = path.dirname(filePath);
            if (!fs.existsSync(dir)) {
                fs.mkdirSync(dir, { recursive: true });
            }

            // 写入文件
            await state.workbook.xlsx.writeFile(filePath);
            logger.info(`Excel文件已保存: ${filePath}`);
            return {
                success: true,
                filePath
            };
        } catch (error) {
            logger.error(`Excel文件保存失败: ${error.message}`);
            return {
                success: false,
                error: error.message
            };
        }
    };

    /**
     * 生成Buffer
     * @returns {Promise<Buffer>} Excel文件的Buffer
     */
    const toBuffer = async () => {
        try {
            return await state.workbook.xlsx.writeBuffer();
        } catch (error) {
            logger.error(`生成Excel Buffer失败: ${error.message}`);
            throw error;
        }
    };

    // 导出的方法集合
    const exporter = {
        createSheet,
        setColumns,
        addHeader,
        addRows,
        setColumnWidths,
        mergeCells,
        setCellStyle,
        saveToFile,
        toBuffer
    };

    return exporter;
};

/**
 * 快速导出数据到Excel文件
 * @param {Object} options 导出选项
 * @param {String} options.filePath 文件保存路径
 * @param {String} options.sheetName 工作表名称
 * @param {Array} options.headers 表头数组
 * @param {Array} options.data 数据数组
 * @param {Object} options.columnWidths 列宽配置
 * @param {Object} options.headerStyle 表头样式
 * @returns {Promise} 导出结果Promise
 */
const quickExport = async (options) => {
    const exporter = createExcelExporter();
    exporter.createSheet(options.sheetName);

    if (options.headers && options.headers.length > 0) {
        exporter.addHeader(options.headers, options.headerStyle);
    }

    if (options.data && options.data.length > 0) {
        exporter.addRows(options.data);
    }

    if (options.columnWidths) {
        exporter.setColumnWidths(options.columnWidths);
    }

    return await exporter.saveToFile(options.filePath);
};

// 使用示例
/*
// 方式一：链式调用
const exporter = createExcelExporter();
exporter
  .createSheet('用户数据')
  .addHeader(['用户ID', '姓名', '年龄', '邮箱'])
  .addRows([
    [1, '张三', 28, 'zhangsan@example.com'],
    [2, '李四', 32, 'lisi@example.com'],
    [3, '王五', 45, 'wangwu@example.com']
  ])
  .setColumnWidths({ A: 10, B: 15, C: 10, D: 30 })
  .saveToFile('./export/users.xlsx');

// 方式二：快速导出
await quickExport({
  filePath: './export/users.xlsx',
  sheetName: '用户数据',
  headers: ['用户ID', '姓名', '年龄', '邮箱'],
  data: [
    [1, '张三', 28, 'zhangsan@example.com'],
    [2, '李四', 32, 'lisi@example.com'],
    [3, '王五', 45, 'wangwu@example.com']
  ],
  columnWidths: { A: 10, B: 15, C: 10, D: 30 }
});
*/

export default {
    createExcelExporter,
    quickExport
};